home *** CD-ROM | disk | FTP | other *** search
/ Personal Computer World 2005 October / PCWOCT05.iso / Software / FromTheMag / XAMPP 1.4.14 / xampp-win32-1.4.14-installer.exe / xampp / php / pear / HTML / Progress / monitor.php < prev    next >
Encoding:
PHP Script  |  2004-03-24  |  19.4 KB  |  558 lines

  1. <?php
  2. // +----------------------------------------------------------------------+
  3. // | PHP Version 4                                                        |
  4. // +----------------------------------------------------------------------+
  5. // | Copyright (c) 1997-2004 The PHP Group                                |
  6. // +----------------------------------------------------------------------+
  7. // | This source file is subject to version 3.0 of the PHP license,       |
  8. // | that is bundled with this package in the file LICENSE, and is        |
  9. // | available at through the world-wide-web at                           |
  10. // | http://www.php.net/license/3_0.txt.                                  |
  11. // | If you did not receive a copy of the PHP license and are unable to   |
  12. // | obtain it through the world-wide-web, please send a note to          |
  13. // | license@php.net so we can mail you a copy immediately.               |
  14. // +----------------------------------------------------------------------+
  15. // | Author: Laurent Laville <pear@laurent-laville.org>                   |
  16. // +----------------------------------------------------------------------+
  17. //
  18. // $Id: monitor.php,v 1.2 2004/02/10 11:46:52 farell Exp $
  19.  
  20. require_once ('HTML/Progress/Error/Raise.php');
  21. require_once ('HTML/Progress.php');
  22. require_once ('HTML/QuickForm.php');
  23.  
  24. /**
  25.  * The HTML_Progress_Monitor class allow an easy way to display progress
  26.  * in a dialog. The user can cancel the task.
  27.  *
  28.  * @version    1.1
  29.  * @author     Laurent Laville <pear@laurent-laville.org>
  30.  * @access     public
  31.  * @category   HTML
  32.  * @package    HTML_Progress
  33.  * @license    http://www.php.net/license/3_0.txt  PHP License 3.0
  34.  */
  35.  
  36. class HTML_Progress_Monitor
  37. {
  38.     /**
  39.      * Instance-specific unique identification number.
  40.      *
  41.      * @var        integer
  42.      * @since      1.0
  43.      * @access     private
  44.      */
  45.     var $_id;
  46.  
  47.     /**#@+
  48.      * Attributes of monitor form.
  49.      *
  50.      * @var        string
  51.      * @since      1.1
  52.      * @access     public
  53.      */
  54.     var $windowname;
  55.     var $buttonStart;
  56.     var $buttonCancel;
  57.     /**#@-*/
  58.     
  59.     /**
  60.      * Delay in milisecond before each progress cells display.
  61.      * 1000 ms === sleep(1)
  62.      * <strong>usleep()</strong> function does not run on Windows platform.
  63.      *
  64.      * @var        integer
  65.      * @since      1.1
  66.      * @access     private
  67.      * @see        setAnimSpeed()
  68.      */
  69.     var $_anim_speed = 0;
  70.  
  71.     /**
  72.      * The progress object renders into this monitor.
  73.      *
  74.      * @var        object
  75.      * @since      1.0
  76.      * @access     private
  77.      */
  78.     var $_progress;
  79.  
  80.     /**
  81.      * The quickform object that allows the presentation.
  82.      *
  83.      * @var        object
  84.      * @since      1.0
  85.      * @access     private
  86.      */
  87.     var $_form;
  88.  
  89.     /**
  90.      * User callback, is in the format:
  91.      * * $_callback = array('classname', 'functionname');
  92.      * If the callback is not a method, then its just
  93.      * * $_callback = 'functionname';
  94.      *
  95.      * @var        mixed
  96.      * @since      1.1
  97.      * @access     private
  98.      */
  99.     var $_callback = null;
  100.  
  101.     
  102.     /**
  103.      * Constructor Summary
  104.      *
  105.      * o Creates a standard progress bar into a dialog box (QuickForm).
  106.      *   Form name, buttons 'start', 'cancel' labels and style, and 
  107.      *   title of dialog box may also be changed.
  108.      *   <code>
  109.      *   $monitor = new HTML_Progress_Monitor();
  110.      *   </code>
  111.      *
  112.      * o Creates a progress bar into a dialog box, with only a new 
  113.      *   form name.
  114.      *   <code>
  115.      *   $monitor = new HTML_Progress_Monitor($formName);
  116.      *   </code>
  117.      *
  118.      * o Creates a progress bar into a dialog box, with a new form name,
  119.      *   new buttons name and style, and also a different title box.
  120.      *   <code>
  121.      *   $monitor = new HTML_Progress_Monitor($formName, $attributes);
  122.      *   </code>
  123.      *
  124.      * @param      string    $formName      (optional) Name of monitor dialog box (QuickForm)
  125.      * @param      array     $attributes    (optional) List of renderer options
  126.      *
  127.      * @since      1.0
  128.      * @access     public
  129.      * @throws     HTML_PROGRESS_ERROR_INVALID_INPUT
  130.      */
  131.     function HTML_Progress_Monitor($formName = 'ProgressMonitor', $attributes = array())
  132.     {
  133.         $this->_package = 'HTML_Progress_Monitor';
  134.         Error_Raise::initialize($this->_package, array('HTML_Progress', '_getErrorMessage'));
  135.  
  136.         if (!is_string($formName)) {
  137.             return Error_Raise::raise($this->_package, HTML_PROGRESS_ERROR_INVALID_INPUT, 'exception',
  138.                 array('var' => '$formName',
  139.                       'was' => gettype($formName),
  140.                       'expected' => 'string',
  141.                       'paramnum' => 1), PEAR_ERROR_TRIGGER);
  142.  
  143.         } elseif (!is_array($attributes)) {
  144.             return Error_Raise::raise($this->_package, HTML_PROGRESS_ERROR_INVALID_INPUT, 'exception',
  145.                 array('var' => '$attributes',
  146.                       'was' => gettype($attributes),
  147.                       'expected' => 'array',
  148.                       'paramnum' => 2), PEAR_ERROR_TRIGGER);
  149.         }
  150.  
  151.         $this->_id = md5(microtime());
  152.  
  153.         $this->_form = new HTML_QuickForm($formName);
  154.  
  155.         $this->windowname   = isset($attributes['title'])  ? $attributes['title']  : 'In progress ...';
  156.         $this->buttonStart  = isset($attributes['start'])  ? $attributes['start']  : 'Start';
  157.         $this->buttonCancel = isset($attributes['cancel']) ? $attributes['cancel'] : 'Cancel';
  158.         $buttonAttr         = isset($attributes['button']) ? $attributes['button'] : '';
  159.         
  160.         $this->_form->addElement('header', 'windowname', $this->windowname);
  161.         $this->_form->addElement('static', 'progressBar');
  162.         $this->_form->addElement('static', 'progressStatus');
  163.  
  164.         $style = $this->isStarted() ? array('disabled'=>'true') : null;
  165.         
  166.         $buttons[] =& $this->_form->createElement('submit', 'start',  $this->buttonStart, $style);
  167.         $buttons[] =& $this->_form->createElement('submit', 'cancel', $this->buttonCancel);
  168.  
  169.         $buttons[0]->updateAttributes($buttonAttr);
  170.         $buttons[1]->updateAttributes($buttonAttr);
  171.         
  172.         $this->_form->addGroup($buttons, 'buttons', '', ' ', false);
  173.       
  174.         // default embedded progress element with look-and-feel
  175.         $bar = new HTML_Progress();
  176.         $this->setProgressElement($bar);
  177.  
  178.         $str =& $this->_form->getElement('progressStatus');
  179.         $str->setText('<div id="status" class="progressStatus"> </div>');
  180.     }
  181.  
  182.     /**
  183.      * Set the sleep delay in milisecond before each progress cells display.
  184.      *
  185.      * @param      integer   $delay         Delay in milisecond.
  186.      *
  187.      * @return     void
  188.      * @since      1.1
  189.      * @access     public
  190.      * @throws     HTML_PROGRESS_ERROR_INVALID_INPUT
  191.      */
  192.     function setAnimSpeed($delay)
  193.     {
  194.         if (!is_int($delay)) {
  195.             return Error_Raise::raise($this->_package, HTML_PROGRESS_ERROR_INVALID_INPUT, 'exception',
  196.                 array('var' => '$delay',
  197.                       'was' => gettype($delay),
  198.                       'expected' => 'integer',
  199.                       'paramnum' => 1), PEAR_ERROR_TRIGGER);
  200.  
  201.         } elseif ($delay < 0) {
  202.             return Error_Raise::raise($this->_package, HTML_PROGRESS_ERROR_INVALID_INPUT, 'error',
  203.                 array('var' => '$delay',
  204.                       'was' => $delay,
  205.                       'expected' => 'greater than zero',
  206.                       'paramnum' => 1), PEAR_ERROR_TRIGGER);
  207.  
  208.         } elseif ($delay > 1000) {
  209.             return Error_Raise::raise($this->_package, HTML_PROGRESS_ERROR_INVALID_INPUT, 'error',
  210.                 array('var' => '$delay',
  211.                       'was' => $delay,
  212.                       'expected' => 'less or equal 1000',
  213.                       'paramnum' => 1), PEAR_ERROR_TRIGGER);
  214.         }
  215.         $this->_anim_speed = $delay;
  216.         
  217.         // reflect changes on the observer copy
  218.         $this->_progress->addListener($this);
  219.     }
  220.  
  221.     /**
  222.      * Listens all progress events from this monitor.
  223.      *
  224.      * @param      mixed     $event         A hash describing the progress event.
  225.      *
  226.      * @return     void
  227.      * @since      1.0
  228.      * @access     public
  229.      * @throws     HTML_PROGRESS_ERROR_INVALID_INPUT
  230.      * @see        callProgressHandler()
  231.      */
  232.     function notify($event)
  233.     {
  234.         if (!is_array($event)) {
  235.             return Error_Raise::raise($this->_package, HTML_PROGRESS_ERROR_INVALID_INPUT, 'exception',
  236.                 array('var' => '$event',
  237.                       'was' => gettype($event),
  238.                       'expected' => 'array',
  239.                       'paramnum' => 1), PEAR_ERROR_TRIGGER);
  240.         }
  241.         $log = strtolower($event['log']);
  242.         if ($log == 'incvalue') {
  243.  
  244.             if (!is_null($this->_callback)) {
  245.                 $this->callProgressHandler($event['value'], $this);
  246.             }
  247.             $this->_progress->display();
  248.             // sleep a bit ...
  249.             for ($i=0; $i<($this->_anim_speed*1000); $i++) { }
  250.                  
  251.             if ($this->_progress->getPercentComplete() == 1) {
  252.                 if ($this->_progress->isIndeterminate()) {
  253.                     $this->_progress->setValue(0);
  254.                 } else {
  255.                     // the progress bar has reached 100%
  256.                     $this->_progress->removeListener($this);
  257.                 }
  258.             } else {
  259.                 $this->_progress->incValue();
  260.             }
  261.         }
  262.     }
  263.  
  264.     /**
  265.      * Sets a user-defined progress handler function.
  266.      *
  267.      * @param      callback  $handler       Name of function or a class-method.
  268.      *
  269.      * @return     void
  270.      * @since      1.1
  271.      * @access     public
  272.      * @throws     HTML_PROGRESS_ERROR_INVALID_INPUT
  273.      * @throws     HTML_PROGRESS_ERROR_INVALID_CALLBACK
  274.      * @see        callProgressHandler()
  275.      */
  276.     function setProgressHandler($handler)
  277.     {
  278.         if (is_array($handler) && count($handler) == 2) {
  279.             list($className, $methodName) = $handler;
  280.             if (class_exists($className)) {
  281.                 $obj = new $className();
  282.                 if (!method_exists($obj, $methodName)) {
  283.                     return Error_Raise::raise($this->_package, HTML_PROGRESS_ERROR_INVALID_CALLBACK, 'error',
  284.                         array('var' => '$handler[1]',
  285.                               'element' => 'Class-Method',
  286.                               'was' => $methodName,
  287.                               'paramnum' => 1), PEAR_ERROR_TRIGGER);
  288.                 }
  289.             } else {
  290.                 return Error_Raise::raise($this->_package, HTML_PROGRESS_ERROR_INVALID_CALLBACK, 'error',
  291.                     array('var' => '$handler[0]',
  292.                           'element' => 'Class',
  293.                           'was' => $className,
  294.                           'paramnum' => 1), PEAR_ERROR_TRIGGER);
  295.             }
  296.         } elseif (is_string($handler)) {
  297.             if (!function_exists($handler)) {
  298.                 return Error_Raise::raise($this->_package, HTML_PROGRESS_ERROR_INVALID_CALLBACK, 'error',
  299.                     array('var' => '$handler',
  300.                           'element' => 'Function',
  301.                           'was' => $handler,
  302.                           'paramnum' => 1), PEAR_ERROR_TRIGGER);
  303.             }
  304.         } else {
  305.             return Error_Raise::raise($this->_package, HTML_PROGRESS_ERROR_INVALID_INPUT, 'exception',
  306.                 array('var' => '$handler',
  307.                       'was' => gettype($handler),
  308.                       'expected' => 'array(class,method) | string(function)',
  309.                       'paramnum' => 1), PEAR_ERROR_TRIGGER);
  310.         }
  311.         $this->_callback = $handler;
  312.  
  313.         // reflect changes on the observer copy
  314.         $this->_progress->addListener($this);
  315.     }
  316.  
  317.     /**
  318.      * Calls a user-defined progress handler function.
  319.      *
  320.      * @param      integer   $arg           Current value of the progress bar.
  321.      * @param      object    $monitor       Reference to this monitor.
  322.      *
  323.      * @return     mixed
  324.      * @since      1.1
  325.      * @access     public
  326.      * @throws     HTML_PROGRESS_ERROR_INVALID_INPUT
  327.      * @see        setProgressHandler(), notify()
  328.      */
  329.     function callProgressHandler($arg, &$monitor)
  330.     {
  331.         if (!is_int($arg)) {
  332.             return Error_Raise::raise($this->_package, HTML_PROGRESS_ERROR_INVALID_INPUT, 'exception',
  333.                 array('var' => '$arg',
  334.                       'was' => gettype($arg),
  335.                       'expected' => 'integer',
  336.                       'paramnum' => 1), PEAR_ERROR_TRIGGER);
  337.  
  338.         } elseif (!is_object($monitor)) {
  339.             return Error_Raise::raise($this->_package, HTML_PROGRESS_ERROR_INVALID_INPUT, 'exception',
  340.                 array('var' => '$monitor',
  341.                       'was' => gettype($monitor),
  342.                       'expected' => 'HTML_Progress_Monitor object',
  343.                       'paramnum' => 2), PEAR_ERROR_TRIGGER);
  344.         }
  345.         
  346.         if (is_null($this->_callback)) {
  347.             return true;                         // no callback yet defined
  348.         } elseif (is_array($this->_callback)) {
  349.             list($className, $methodName) = $this->_callback;
  350.             $obj = new $className();
  351.             return call_user_func(array(&$obj, $methodName), $arg, $monitor);
  352.         } else {
  353.             return call_user_func($this->_callback, $arg, $monitor);
  354.         }
  355.     }
  356.  
  357.     /**
  358.      * Returns TRUE if progress was started by user, FALSE otherwise.
  359.      *
  360.      * @return     bool
  361.      * @since      1.1
  362.      * @access     public
  363.      */
  364.     function isStarted()
  365.     {
  366.         $action = $this->_form->getSubmitValues();
  367.         return isset($action['start']);
  368.     }
  369.  
  370.     /**
  371.      * Returns TRUE if progress was canceled by user, FALSE otherwise.
  372.      *
  373.      * @return     bool
  374.      * @since      1.0
  375.      * @access     public
  376.      */
  377.     function isCanceled()
  378.     {
  379.         $action = $this->_form->getSubmitValues();
  380.         return isset($action['cancel']);
  381.     }
  382.  
  383.     /**
  384.      * Display Monitor and catch user action (cancel button).
  385.      *
  386.      * @return     void
  387.      * @since      1.0
  388.      * @access     public
  389.      */
  390.     function run()
  391.     {
  392.         if ($this->isStarted()) {
  393.             $this->_progress->incValue();
  394.         }
  395.     }
  396.  
  397.     /**
  398.      * Attach a progress bar to this monitor.
  399.      *
  400.      * @param      object    $bar           a html_progress instance
  401.      *
  402.      * @return     void
  403.      * @since      1.1
  404.      * @access     public
  405.      * @throws     HTML_PROGRESS_ERROR_INVALID_INPUT
  406.      * @see        getProgressElement()
  407.      */
  408.     function setProgressElement($bar)
  409.     {
  410.         if (!is_a($bar, 'HTML_Progress')) {
  411.             return Error_Raise::raise($this->_package, HTML_PROGRESS_ERROR_INVALID_INPUT, 'exception',
  412.                 array('var' => '$bar',
  413.                       'was' => gettype($bar),
  414.                       'expected' => 'HTML_Progress object',
  415.                       'paramnum' => 1), PEAR_ERROR_TRIGGER);
  416.         }
  417.         $this->_progress = $bar;
  418.         $this->_progress->addListener($this);
  419.  
  420.         $bar =& $this->_form->getElement('progressBar');
  421.         $bar->setText( $this->_progress->toHtml() );
  422.     }
  423.  
  424.     /**
  425.      * Returns a reference to the progress bar object 
  426.      * used with the monitor.
  427.      *
  428.      * @return     object
  429.      * @since      1.1
  430.      * @access     public
  431.      * @see        setProgressElement()
  432.      */
  433.     function &getProgressElement()
  434.     {
  435.         return $this->_progress;
  436.     }
  437.  
  438.     /**
  439.      * Returns progress styles (StyleSheet).
  440.      *
  441.      * @return     string
  442.      * @since      1.0
  443.      * @access     public
  444.      */
  445.     function getStyle()
  446.     {
  447.         return $this->_progress->getStyle();
  448.     }
  449.  
  450.     /**
  451.      * Returns progress javascript.
  452.      *
  453.      * @return     string
  454.      * @since      1.0
  455.      * @access     public
  456.      */
  457.     function getScript()
  458.     {
  459.         $js = "
  460. function setStatus(pString)
  461. {
  462.         if (isDom)
  463.             prog = document.getElementById('status');
  464.         if (isIE)
  465.             prog = document.all['status'];
  466.         if (isNS4)
  467.             prog = document.layers['status'];
  468.     if (prog != null) 
  469.         prog.innerHTML = pString;
  470. }";
  471.         return $this->_progress->getScript() . $js;
  472.     }
  473.  
  474.     /**
  475.      * Returns Monitor forms as a Html string.
  476.      *
  477.      * @return     string
  478.      * @since      1.0
  479.      * @access     public
  480.      */
  481.     function toHtml()
  482.     {
  483.         return $this->_form->toHtml();
  484.     }
  485.  
  486.     /**
  487.      * Accepts a renderer
  488.      *
  489.      * @param      object    $renderer      An HTML_QuickForm_Renderer object
  490.      *
  491.      * @return     void
  492.      * @since      1.1
  493.      * @access     public
  494.      */
  495.     function accept(&$renderer)
  496.     {
  497.         if (!is_a($renderer, 'HTML_QuickForm_Renderer')) {
  498.             return Error_Raise::raise($this->_package, HTML_PROGRESS_ERROR_INVALID_INPUT, 'exception',
  499.                 array('var' => '$renderer',
  500.                       'was' => gettype($renderer),
  501.                       'expected' => 'HTML_QuickForm_Renderer object',
  502.                       'paramnum' => 1), PEAR_ERROR_TRIGGER);
  503.         }
  504.         $this->_form->accept($renderer);
  505.     }
  506.  
  507.     /**
  508.      * Display a caption on action in progress.
  509.      *
  510.      * The idea of a simple utility function for replacing variables 
  511.      * with values in an message template, come from sprintfErrorMessage
  512.      * function of Error_Raise package by Greg Beaver.
  513.      *
  514.      * This simple str_replace-based function can be used to have an
  515.      * order-independent sprintf, so messages can be passed in
  516.      * with different grammar ordering, or other possibilities without
  517.      * changing the source code.
  518.      *
  519.      * Variables should simply be surrounded by % as in %varname%
  520.      *
  521.      * @param      string    $caption       (optional) message template
  522.      * @param      array     $args          (optional) associative array of 
  523.      *                                      template var -> message text
  524.      * @since      1.1
  525.      * @access     public
  526.      */
  527.     function setCaption($caption = ' ', $args = array() )
  528.     {
  529.         if (!is_string($caption)) {
  530.             return Error_Raise::raise($this->_package, HTML_PROGRESS_ERROR_INVALID_INPUT, 'exception',
  531.                 array('var' => '$caption',
  532.                       'was' => gettype($caption),
  533.                       'expected' => 'string',
  534.                       'paramnum' => 1), PEAR_ERROR_TRIGGER);
  535.  
  536.         } elseif (!is_array($args)) {
  537.             return Error_Raise::raise($this->_package, HTML_PROGRESS_ERROR_INVALID_INPUT, 'exception',
  538.                 array('var' => '$args',
  539.                       'was' => gettype($args),
  540.                       'expected' => 'array',
  541.                       'paramnum' => 2), PEAR_ERROR_TRIGGER);
  542.         }
  543.  
  544.         foreach($args as $name => $value) {
  545.             $caption = str_replace("%$name%", $value, $caption);
  546.         }
  547.         if (function_exists('ob_get_clean')) {
  548.             $status  = ob_get_clean();      // use for PHP 4.3+
  549.         } else {
  550.             $status  = ob_get_contents();   // use for PHP 4.2+
  551.             ob_end_clean();
  552.         }
  553.         $status = '<script type="text/javascript">self.setStatus(\''.$caption.'\'); </script>';
  554.         echo $status;
  555.         ob_start();
  556.     }
  557. }
  558. ?>